맨위로가기

Goto 문

"오늘의AI위키"는 AI 기술로 일관성 있고 체계적인 최신 지식을 제공하는 혁신 플랫폼입니다.
"오늘의AI위키"의 AI를 통해 더욱 풍부하고 폭넓은 지식 경험을 누리세요.

1. 개요

goto 문은 프로그래밍 언어에서 특정 레이블로 프로그램의 실행 흐름을 변경하는 데 사용되는 제어문이다. goto 문은 조건문과 결합하여 조건부 제어 전송을 수행하며, 레이블이 붙은 문과 함께 사용된다. 1960~70년대에 구조적 프로그래밍 지지자들은 goto 문이 프로그램의 구조를 해치고 가독성을 떨어뜨린다고 비판하며, 순환문, if-then-else문과 같은 '구조적' 흐름 제어문을 사용할 것을 주장했다. 반면 goto 문 옹호자들은 특정 상황에서 코드를 간결하고 효율적으로 만들 수 있다고 반박하며, 다중 루프 탈출이나 예외 처리 등에 유용하다고 주장한다. 현대 프로그래밍 언어에서는 goto 문 사용이 감소하는 추세이나, C와 같은 언어에서는 제한적으로 사용되며, 리눅스 커널과 같은 대규모 프로젝트에서도 발견된다.

광고

더 읽어볼만한 페이지

  • 에츠허르 데이크스트라 - 교착 상태
    교착 상태는 둘 이상의 프로세스가 자원을 점유하고 서로의 자원을 요청하여 더 이상 진행할 수 없는 상태를 의미하며, 상호 배제, 점유 대기, 비선점, 순환 대기 네 가지 조건이 모두 충족되어야 발생하고, 운영 체제는 이를 예방, 회피, 무시, 발견하는 방법으로 관리한다.
  • 에츠허르 데이크스트라 - 세마포어
    세마포어는 데이크스트라가 고안한 정수 변수로, P/V 연산을 통해 자원 접근을 제어하고 동기화 문제를 해결하며, 계수 세마포어와 이진 세마포어로 나뉘어 멀티스레드 환경에서 자원 관리 및 스레드 동기화에 기여한다.
  • 제어 흐름 - 프로그램 카운터
    프로그램 카운터는 CPU 내에서 다음에 실행될 명령어의 주소를 저장하는 레지스터로, 명령어 사이클의 fetch 단계에서 사용되어 명령어를 가져오고 실행 후 갱신되며, CPU 성능 향상 기술과 현대 프로그래밍 모델에 영향을 미친다.
  • 제어 흐름 - 예외 처리
    예외 처리는 프로그램 실행 중 예외 발생 시 정상적인 실행 흐름을 유지하거나 안전하게 종료하기 위한 메커니즘으로, 많은 프로그래밍 언어에서 제공하며 예외 안전성을 목표로 한다.
  • 프로그래밍 구성체 - 형 변환
    형 변환은 프로그래밍에서 변수의 데이터 타입을 변경하는 것으로, 암시적 형 변환과 명시적 형 변환으로 나뉘며, 객체 지향 프로그래밍에서는 업캐스팅과 다운캐스팅이 발생하고, 각 언어는 고유한 규칙과 방법을 제공하며 잘못된 형 변환은 오류를 유발할 수 있다.
  • 프로그래밍 구성체 - 연산자 오버로딩
    연산자 오버로딩은 프로그래밍 언어에서 기존 연산자를 사용자 정의 자료형에 대해 재정의하여 내장 자료형처럼 다루도록 하는 기능으로, 코드 가독성과 표현력을 높이지만 남용 시 코드 의미를 모호하게 만들 수 있다.

2. 사용법

'''goto''' ''레이블'' 형식으로 사용한다.

'''goto''' 문은 특정 레이블이 있는 곳으로 프로그램의 실행 흐름을 무조건 이동시키는 명령어이다. 이는 기계어의 분기 명령어 중 무조건 분기와 어셈블리 언어의 레이블 개념을 절차적 프로그래밍에 가져온 것으로 볼 수 있다. '''goto''' 문 자체만으로는 기능을 수행할 수 없으며, 반드시 이동할 목표 지점인 레이블이 코드 내에 정의되어 있어야 한다.

'''goto''' 문은 종종 if 문과 결합하여 조건에 따라 프로그램 실행 위치를 변경하는 데 사용된다.

'''IF''' ''조건'' '''THEN''' '''goto''' ''레이블''

이러한 조건부 분기는 반복문(루프)을 구현하거나 특정 코드 블록을 건너뛰는 등의 기능을 수행하는 데 활용될 수 있다.

프로그래밍 언어마다 '''goto''' 문의 사용 가능 범위나 대상에 대한 제약이 다르다. 예를 들어, C 언어에서는 현재 실행 중인 함수 외부(다른 함수 내부)에 있는 레이블로는 직접 점프할 수 없다. 하지만 setjmp/longjmp 함수를 사용하면 호출 스택을 거슬러 올라가는 형태의 비지역적 점프(non-local jump)는 가능하다.

'''goto''' 문은 코드의 흐름을 이해하기 어렵게 만들 수 있다는 비판을 받는다. 단순히 '''goto''' 문만 봐서는 해당 지점으로 이동하는 목적이 이전에 실행했던 코드로 돌아가 반복(루프)하려는 것인지, 아니면 단순히 특정 코드 부분을 건너뛰려는 것인지 명확히 알기 어렵기 때문이다. if 문이나 while 문 등으로 더 명확하고 구조적으로 작성할 수 있는 경우에는 '''goto''' 사용을 지양하는 것이 좋다.

하지만 여러 단계로 중첩된 반복문이나 조건문 블록을 한 번에 빠져나가야 하는 경우처럼, '''goto'''를 사용하는 것이 오히려 코드를 더 간결하고 이해하기 쉽게 만드는 경우도 있다. (예를 들어, 자바처럼 goto를 지원하지 않는 언어에서는 레이블이 붙은 break 문 등을 사용하여 비슷한 기능을 구현한다.) 따라서 특히 C 언어와 같이 '''goto'''를 지원하는 환경에서는 무조건적으로 사용을 배제하기보다는 상황에 맞게 적절히 활용하는 것이 권장된다.

자원을 할당하고 해제하는 코드처럼 프로그램의 특정 진입점과 탈출점이 반드시 일치해야 하는 로직에서는 '''goto'''뿐만 아니라 중간에서 함수를 종료시키는 return 문 등의 사용도 제한될 수 있다. 이러한 특수한 경우의 제약을 일반적인 모든 코드 작성에 적용해서는 안 된다는 점에 유의해야 한다.

아래는 C 언어에서 '''goto''' 문을 사용하는 간단한 예시이다. 레이블(여기서는 `clear`)은 콜론(`:`)으로 끝나며, 해당 레이블이 붙은 문장으로 실행 흐름이 이동한다. (C 언어에서는 구문상 제약으로 레이블 단독 사용이 불가능하고 반드시 '레이블이 붙은 문' 형태여야 하지만, 다른 언어에서는 레이블만으로도 충분한 경우가 있다.)



clear:

x = 0;

/* ... 중간 처리 코드 ... */

goto clear; /* clear 레이블로 이동 */



위 코드에서 `goto clear;` 문이 실행되면 프로그램은 `clear:` 레이블이 있는 곳으로 이동하여 `x = 0;`부터 다시 실행하게 된다.

참고로, 점프의 방향을 반대로 하여 점프 도착 지점에 `come from` 문을 두고 점프 출발 지점에 레이블을 두는 컴프롬 문이라는 개념도 농담처럼 제안된 바 있다.[10] 비록 제안 자체는 유머였지만, 실제로 이와 유사한 기능을 가진 프로그래밍 언어들이 존재하며 프로그램 이론 연구의 대상이 되기도 한다.

3. 비판

고급 언어에서 `goto` 문은 오랫동안 비판의 대상이 되어 왔다. 가장 큰 이유는 `goto` 문을 과도하게 사용하면 프로그램의 제어 흐름이 복잡하게 얽혀 코드를 읽고 이해하기 어려우며, 유지보수가 힘든 이른바 스파게티 코드를 만들기 쉽기 때문이다.[25]

1960년대1970년대구조적 프로그래밍이 중요한 프로그래밍 원칙으로 부상하면서 이러한 비판은 더욱 거세졌다. 많은 컴퓨터 과학자들은 프로그램의 논리 구조를 명확하게 표현하기 위해 `goto` 문 대신 순환문(loop)이나 `if-then-else` 문과 같은 구조적인 제어 흐름 구문을 사용해야 한다고 주장했다.[25]

`goto` 문에 대한 가장 유명하고 영향력 있는 비판은 1968년 에츠허르 데이크스트라가 발표한 "Go To Statement Considered Harmful"(goto 문은 해롭다고 간주된다)이라는 제목의 서신이다.[26] 데이크스트라는 이 글에서 `goto` 문이 프로그램의 실행 흐름을 예측하기 어렵게 만들어 프로그램의 정확성을 분석하고 증명하는 작업을 매우 복잡하게 만든다고 지적하며, 고급 언어에서는 `goto` 문을 폐지해야 한다고 주장했다.[1] 이 서신은 프로그래밍 커뮤니티 내에서 `goto` 사용에 대한 격렬한 논쟁을 촉발하는 계기가 되었다.[2]

`goto` 문은 프로그램의 구조화를 방해하고 디버깅을 어렵게 만들며, 버그 발생 가능성을 높이는 원인으로 지목된다. 제어 흐름이 예측 불가능하게 여러 곳으로 이동할 수 있기 때문에 코드의 특정 부분에 도달하는 경로를 추적하기 어렵고, 이는 잠재적인 오류를 찾거나 수정하는 작업을 힘들게 만든다. 또한, `goto` 문 자체만으로는 "이전에 실행한 위치로 돌아가는" 반복의 의미인지, 아니면 "특정 코드 블록을 건너뛰는" 점프의 의미인지 명확히 드러나지 않아 코드의 의도를 파악하기 어렵게 만든다.

실제로 `goto` 문과 관련된 심각한 소프트웨어 오류 사례도 존재한다. 1990년 AT&T의 장거리 전화망을 마비시켰던 대규모 장애는 제어 흐름 변경과 관련된 문제였으며[24], 2014년 애플SSL/TLS 구현에서 발견된 심각한 보안 취약점(CVE-2014-1266), 일명 '''goto fail''' 버그는 `goto` 문을 잘못 사용하여 필수적인 보안 검증 로직을 건너뛰게 만든 것이 원인이었다. 이러한 사례들은 `goto` 문이 코드의 논리적 오류를 유발하고 발견하기 어렵게 만들 수 있음을 보여준다.

이러한 비판과 문제점 때문에 많은 현대 프로그래밍 언어(Java, Python 등)는 아예 `goto` 문을 지원하지 않거나 사용을 강력히 권장하지 않는다. 비록 특정 상황에서 `goto`가 간결한 해결책이 될 수 있다는 주장도 있지만[27], 구조적 프로그래밍 원칙과 코드의 명확성, 유지보수성을 중시하는 현대 소프트웨어 개발 환경에서는 `goto` 사용을 최소화하거나 피하는 것이 일반적인 경향이다.

3. 1. goto 문 논쟁

고급 프로그래밍 언어에서 goto 문은 오랫동안 논쟁의 대상이었다. 특히 goto 문을 과도하게 사용하면 코드가 복잡하게 얽혀 이해하고 유지보수하기 어려운 스파게티 코드가 되기 쉽다는 비판이 제기되었다. 1960년대1970년대구조적 프로그래밍이 부상하면서, 많은 컴퓨터 과학자들은 프로그램 제어 흐름을 위해 goto 문 대신 순환문이나 if-then-else 문과 같은 구조적인 방식을 사용해야 한다고 주장했다.[25]

goto 문에 대한 가장 유명한 비판은 1968년 에츠허르 데이크스트라가 발표한 "'''Go To Statement Considered Harmful'''"(GOTO 문은 해롭다고 간주된다)이라는 제목의 서신이다.[26] 데이크스트라는 이 글에서 goto 문이 프로그램의 정확성을 분석하고 증명하는 과정을 복잡하게 만들기 때문에 고급 언어에서는 사용을 제한하거나 폐지해야 한다고 강하게 주장했다.[1] 이 서신은 프로그래밍 커뮤니티 내에서 goto 사용에 대한 격렬한 논쟁을 불러일으켰다.[2]

하지만 모든 프로그래머가 데이크스트라의 의견에 동의한 것은 아니다. 일부 프로그래머들은 goto 문이 특정 상황에서는 코드를 더 간결하고 효율적으로 만들 수 있다고 반박했다. 예를 들어, 여러 겹으로 중첩된 반복문을 한 번에 빠져나가거나 예외 처리를 위해 특정 코드로 이동해야 할 때 goto 문이 유용할 수 있다는 것이다. 도널드 커누스는 그의 저서 'goto 문을 사용한 구조적 프로그래밍'[27]에서 특정 프로그래밍 구조가 언어 자체에 없을 때 goto 문이 이를 대체하는 효과적인 수단이 될 수 있다고 분석했다. 브라이언 커니핸데니스 리치 역시 C 언어 서적에서 goto의 남용 가능성을 경고하면서도, 함수 종료 시 오류 처리나 다단계 루프 탈출과 같은 특정 상황에서의 유용성을 인정했다. 리눅스 커널 개발자인 리누스 토르발스나 소프트웨어 엔지니어 스티브 매코넬 등도 goto 문이 코드의 속도, 크기, 명확성을 향상시킬 수 있는 유용한 기능이며, 프로그래머가 신중하게 사용한다면 문제가 없다는 입장을 보였다. 실제로 리눅스 커널 코드에는 여전히 많은 goto 문이 사용되고 있다.

1966년 발표된 뵈임-자코피니 정리는 모든 알고리즘이 순차(sequence), 선택(selection), 반복(iteration)이라는 세 가지 기본 제어 구조만으로 표현될 수 있음을 수학적으로 증명했다. 이 정리는 구조적 프로그래밍의 이론적 토대를 마련했지만, goto 문 논쟁을 완전히 끝내지는 못했다. 이론적으로는 goto 없이 프로그램을 작성할 수 있지만, 실제로는 추가적인 변수를 사용해야 하거나 코드 구조가 더 복잡해져 오히려 가독성을 해칠 수 있다는 지적이 있었다. 커누스는 정리에 따라 기계적으로 goto를 제거하는 것이 오히려 프로그램의 구조를 파괴할 수 있다고 경고하며, 뵈임-자코피니 정리가 goto를 사용하지 않는 것이 항상 더 나은 프로그래밍 방식임을 의미하지는 않는다고 주장했다.

시간이 흐르면서 1970년대1980년대에 구조적 프로그래밍이 주류 패러다임으로 자리 잡으면서 goto 문의 사용 빈도는 점차 감소했다. FORTRAN은 1978년 구조적 프로그래밍 구문을 도입하며 goto 사용에 제약을 두기 시작했고, 이후 개정판에서는 일부 형태의 goto 문을 아예 삭제했다.[3][4] Java나 Python과 같이 널리 사용되는 현대 프로그래밍 언어 중 일부는 goto 문 자체를 지원하지 않는다. 하지만 C와 같은 언어에서는 여전히 goto 문을 사용할 수 있으며, PHP는 2009년 버전 5.3부터 goto 문을 새롭게 추가[11]하는 등, 언어 설계에 따라 다른 접근 방식을 보이고 있다. MISRA C와 같은 코딩 표준에서도 초기에는 goto 사용을 금지했지만, 이후에는 특정 조건(순방향 점프) 하에서는 허용하는 방향으로 완화되기도 했다.

결론적으로, goto 문 사용에 대한 논쟁은 프로그래밍 스타일과 특정 상황에서의 실용성 문제로 요약될 수 있다. 프로그래밍 커뮤니티의 오랜 논의처럼, goto를 무분별하게 사용하면 스파게티 코드를 초래하기 쉽지만, 맹목적으로 금지하는 것만이 좋은 코드를 보장하지는 않는다. 다중 루프 탈출이나 오류 처리 루틴 통합 등 일부 제한적인 상황에서는 goto가 여전히 유용할 수 있으며, 중요한 것은 프로그래머가 그 장단점을 이해하고 신중하게 사용하는 것이다.

3. 2. 데이크스트라의 주장

고급 언어에서 goto 문은 종종 비판의 대상이 되어 왔는데, 과도하게 사용될 경우 코드를 읽고 유지보수하기 어려운 스파게티 코드를 만들기 쉽기 때문이다. 특히 구조적 프로그래밍이 강조되던 1960년대1970년대에는 많은 컴퓨터 과학자들이 프로그램 제어 흐름에 goto 문 대신 순환문이나 if-then-else문 같은 구조적인 제어문을 사용해야 한다고 주장했다.[25]

goto 문에 대한 가장 유명한 비판 중 하나는 1968년 에츠허르 데이크스트라가 발표한 '''Go To Statement Considered Harmful'''(goto 문은 해롭다고 간주된다)이라는 제목의 서신이다.[26][1] 이 서신은 학술지 'Communications of the ACM'에 실리면서 큰 논쟁을 불러일으켰다. 데이크스트라는 이 글에서 고급 프로그래밍 언어에서 goto 문의 사용을 제한하거나 폐지해야 한다고 강력히 주장했다.

그의 핵심 주장은 프로그램의 정적인 텍스트 구조와 프로그램이 실행될 때의 동적인 프로세스 구조 사이의 간극을 최대한 줄여야 한다는 것이었다. 인간은 시간의 흐름에 따라 변화하는 동적인 프로세스를 파악하는 능력보다 정적인 관계를 파악하는 능력이 더 뛰어나므로, 두 구조를 최대한 일치시키는 것이 프로그램의 정확성을 이해하고 검증하는 데 중요하다고 보았다. 이를 위해서는 프로그램의 실행 상태를 나타내는 간결한 지표(예: 현재 실행 중인 행 번호, 스택 트레이스, 루프 반복 횟수 등)가 필요한데, goto 문을 자유롭게 사용하면 이러한 간결한 지표를 만들거나 추적하기 어려워진다고 지적했다. 특히 순환문을 포함하는 프로그램의 경우, goto 문은 실행 흐름을 예측 불가능하게 만들어 정확성을 분석하고 증명하는 작업을 매우 복잡하게 만든다는 것이다.[1][13]

데이크스트라의 이러한 주장은 프로그래밍 커뮤니티에 큰 반향을 일으켰으며, 이후 "GOTO Considered Harmful' Considered Harmful"[2]과 같은 반박과 재반박이 이어지며 오랜 논쟁의 대상이 되었다.

한편 도널드 커누스는 데이크스트라가 그의 다른 주요 저작인 "Structured Programming"[15]에서는 goto 문에 대해 거의 언급하지 않았다고 지적했다.[14] 실제로 해당 저작에서는 제어 흐름은 레이블된 지점으로 이동하는 방식(goto)보다는 순차, 분기, 반복, 프로시저 호출 등으로 구성되어야 한다는 원칙적인 언급만 있을 뿐이다. 또한 데이크스트라는 "Go To Statement Considered Harmful"에서도 특정 제어 구조(순차, 분기, 반복 등)만이 모든 필요를 충족시킨다고 주장하지는 않았으며[13], 소위 "세 가지 기본 구조"에 엄격하게 얽매이지는 않았다.

결론적으로 데이크스트라의 주장은 단순히 goto 문을 사용하지 말자는 차원을 넘어, 프로그램을 이해하고 정확성을 증명하기 쉬운 구조로 작성하는 것, 즉 구조적 프로그래밍의 본질에 대한 깊은 성찰을 담고 있다. 그는 큰 프로그램을 더 작은 단위(서브루틴, 함수 등)로 나누고 각 부분의 정확성을 증명함으로써 전체 프로그램의 신뢰성을 높이는 방식을 강조했다.

3. 3. goto 옹호론

`goto` 문은 과도하게 사용될 경우 코드를 이해하고 유지보수하기 어려운 스파게티 코드를 만들 수 있다는 비판을 받아왔다.[25] 구조적 프로그래밍이 강조되면서 많은 컴퓨터 과학자들은 `goto` 대신 순환문이나 `if-then-else`와 같은 구조적 제어문을 사용해야 한다고 주장했다. 그러나 `goto` 문이 특정 상황에서는 여전히 유용하며, 때로는 `goto` 없이 코드를 작성하기 어렵다는 반론도 꾸준히 제기되었다. 일부 프로그래머들은 `goto` 문을 적절히 사용하면 오히려 프로그램의 속도, 크기, 코드 명확성을 향상시킬 수 있다고 주장한다.

에츠허르 데이크스트라의 유명한 비판("goto 문의 해로움"[26])에도 불구하고, 다른 저명한 컴퓨터 과학자들은 `goto`의 필요성을 강조했다. 도널드 커누스는 'goto 문을 사용한 구조적 프로그래밍'[27]에서 특정 프로그래밍 작업에서는 `goto`가 가장 적합한 언어 구성일 수 있다고 분석했다. 그는 구조적 프로그래밍 정리를 근거로 `goto`를 무조건 배제하는 것이 오히려 프로그램의 구조를 해칠 수 있다고 지적하며, 해당 정리가 보여주는 것은 완전히 "비구조적 프로그래밍"일 수 있음을 경고했다.

C 언어의 공동 개발자인 브라이언 커니핸데니스 리치는 ''The C Programming Language''에서 `goto`가 남용될 수 있음을 경고하면서도, 함수 종료 시 오류 처리 코드를 모으거나 여러 단계의 중첩된 루프를 한 번에 빠져나가는 데 유용하게 사용할 수 있다고 언급했다. 이는 특히 예외 처리 메커니즘이 부족한 C 언어에서 흔히 사용되는 패턴이다.

리눅스 커널 개발자인 리누스 토르발스나 소프트웨어 엔지니어 스티브 매코넬과 같은 현대의 프로그래머들도 `goto`가 여전히 유용한 언어 기능이며, 프로그래머가 분별력을 가지고 신중하게 사용할 경우 프로그램의 속도, 크기, 코드 명확성을 개선하는 데 도움이 될 수 있다고 주장한다. 실제로 컴퓨터 과학 교수 존 레거에 따르면, 2013년 기준으로 리눅스 커널 코드에는 약 10만 개의 `goto` 문이 사용되고 있었다.

`goto` 문이 유용하게 사용될 수 있는 대표적인 상황은 다음과 같다.

  • 다단계 중단(Multi-level break/continue): 여러 겹으로 중첩된 for 문이나 while 문 같은 루프 구조에서 한 번에 바깥으로 빠져나가거나 다음 단계로 넘어갈 때 유용하다. 이는 C에서 자주 사용되는 방식이다. Java는 `goto` 키워드를 예약했지만 구현하지 않는 대신, 레이블이 있는 `break` 및 `continue` 문을 제공하여 이 기능을 지원한다. Java 설명서에 따르면, C 언어에서 `goto` 문의 가장 흔한 사용(약 90%)이 바로 이러한 다단계 중단이었다고 한다.
  • 오류 처리 및 자원 정리: 예외 처리 기능이 없는 언어에서 오류 발생 시 처리를 특정 위치로 모으거나, 함수 종료 전에 할당된 자원을 해제하는 등의 정리 코드를 중앙 집중화하는 데 사용된다. C++에서는 RAII 기법이나 `try-catch` 예외 처리를 통해 이를 대체할 수 있다.
  • 유한 상태 기계 구현: 상태 전이 테이블과 `goto` 문을 사용하여 상태 간의 전환을 구현하는 데 사용될 수 있으며, 특히 자동으로 생성된 코드에서 유용하다.
  • 코드 가독성 및 간결성 향상: 특정 상황에서는 `goto`를 사용하는 것이 코드를 더 읽기 쉽고 따라가기 쉽게 만들며, 코드 중복을 줄여 프로그램을 더 작게 만들 수 있다.
  • 레거시 코드 수정: 대규모 함수나 복잡한 구조를 가진 기존 코드를 수정할 때, 광범위한 리팩터링이나 코드 중복을 피하기 위해 제한적으로 사용될 수 있다.


성능 측면에서도 `goto` 문을 옹호하는 의견이 있었다. `goto` 문을 사용하지 않고 구조적 프로그래밍의 기본 구조만으로 코드를 작성할 경우, 프로그램 실행 속도나 메모리 사용량 측면에서 성능이 저하될 수 있다는 지적이다.[16]

또한, 모든 언어가 `goto`를 배제하는 것은 아니다. PHP는 2009년에 출시된 버전 5.3부터 `goto` 문을 추가했으며[11], 이는 고도화된 언어 구조 속에서도 `goto`가 특정 상황에서 유용하게 쓰일 수 있음을 보여주는 사례이다.

comp.lang.c FAQ 항목 17.10에서는 `goto` 사용 문제를 다루면서, 프로그래밍 스타일은 유연하지 않은 규칙으로 단정하기 어렵다고 설명한다. `goto`를 무분별하게 사용하면 스파게티 코드를 유발하지만, 맹목적으로 금지하는 것 또한 좋은 프로그래밍을 보장하지는 않는다는 것이다. 다단계 `break`나 `switch` 문 내 공통 작업 병합, 여러 오류 반환 지점이 있는 함수에서 정리 작업 중앙 집중화 등 몇몇 잘 제한된 상황에서는 `goto` 사용이 허용될 수 있으며, 중요한 것은 규칙을 맹목적으로 따르기보다 상황에 맞게 현명하게 사용하는 것이라고 강조한다.

4. 변형

'''goto''' 문은 기본적인 형태 외에도 다양한 변형이 존재한다.

=== 계산된 goto 문 (Computed GOTO) ===

계산된 goto 문은 어떤 수식의 값이나 변수에 저장된 레이블을 이용해 프로그램의 여러 지점 중 한 곳으로 이동하는 방식이다.[6] 이는 일반적인 goto 문보다 코드 흐름을 파악하기 어렵게 만들 수 있는데, 프로그래머가 코드를 보더라도 다음에 어떤 부분이 실행될지 예측하기 어렵기 때문이다.


  • '''베이직''': `ON ... GOTO` 문을 통해 수식 값에 따라 지정된 여러 줄 번호 중 하나로 분기할 수 있다. 이는 특정 조건에 따라 여러 경우로 나누어 처리할 때 유용하다.
  • '''C''': 직접적인 계산된 goto는 없지만, Switch 문이 비슷한 기능을 제공한다. 일부 컴파일러(특히 GCC)는 표준 C/C++ 문법이 아닌 확장 기능으로 계산된 goto를 지원하기도 한다. 이 확장 기능을 사용하면, 레이블의 메모리 주소를 얻어 포인터 변수에 저장한 뒤, 이 변수를 이용해 해당 레이블로 점프할 수 있다. 이는 포트란의 할당된 goto와 유사하지만, 임의의 포인터 연산 결과를 점프 대상으로 사용할 수 있다는 점에서 더 유연하다. 단, 점프 대상은 현재 함수 내부에만 있어야 한다.
  • '''포트란''': `GOTO (레이블목록) 변수` 형태의 계산된 `GOTO` 문이 있었다. 예를 들어, `goto (20,30,40) i`는 변수 `i`의 값이 1, 2, 3일 때 각각 20, 30, 40번 줄로 분기한다.[6] 현대 포트란에서는 `SELECT CASE` 구문을 사용하는 것이 권장된다.
  • '''PL/I''': `LABEL` 데이터 타입을 사용하여 계산된 goto와 유사한 기능을 구현할 수 있다. 레이블들을 배열에 저장하고 배열 인덱스를 이용해 원하는 레이블로 분기하는 방식이다.


=== 할당된 goto 문 (Assigned GOTO) ===

할당된 goto 문은 실행 중에 변수에 특정 레이블 값을 할당(저장)해 두었다가, 나중에 이 변수를 이용해 해당 레이블로 이동하는 방식이다.

  • '''포트란''': 포트란 95 이전 버전에서는 `ASSIGN` 문을 사용하여 문장 레이블(줄 번호)을 정수 변수에 할당하고, `GOTO 변수` 형태로 해당 레이블로 점프할 수 있었다. 하지만, 레이블이 할당되지 않은 변수를 사용하거나 할당된 변수 값을 프로그래머가 실수로 변경하는 경우 예기치 않은 동작이나 버그를 유발할 수 있어 문제가 되었다.[4] 이러한 문제 때문에 이후 버전에서는 삭제되었다.[4]



assign 200 to i

i = i+1 ! 프로그래머의 실수로 변수 값이 변경됨

goto i ! 의도하지 않은 곳으로 점프하거나 오류 발생

200 write(*,*) "원래 가려던 레이블"


  • '''PL/I''': `LABEL` 데이터 타입을 사용하여 할당된 goto와 유사한 기능을 구현할 수 있다. 레이블 변수에 특정 레이블 값을 할당한 뒤, 이 변수를 이용해 분기한다.


=== 컨티뉴에이션 (Continuation) ===

컨티뉴에이션(continuation|컨티뉴에이션영어)은 프로그램 실행 중 특정 시점의 상태(실행 위치, 호출 스택 등)를 저장했다가, 나중에 그 상태로 되돌아가 실행을 이어가는 개념이다. 이는 계산된 goto 문과 비슷하게 저장된 위치로 이동한다는 공통점이 있지만, 현재 실행 중인 함수의 범위를 벗어나 점프할 수 있고 호출 스택까지 조절할 수 있다는 점에서 훨씬 유연하고 강력한 제어 구조이다.

  • '''Scheme''': 컨티뉴에이션을 언어 차원에서 강력하게 지원한다. 이를 이용하면 코루틴이나 협력적 멀티태스킹과 같은 복잡한 제어 흐름을 비교적 쉽게 구현할 수 있다.
  • '''C''': setjmp/longjmp 함수를 통해 제한적인 형태의 컨티뉴에이션(주로 현재 함수 바깥의 상위 함수로 탈출하는 용도)을 사용할 수 있다.
  • '''Common Lisp''': `GO` 연산자가 어휘적 범위를 벗어난 점프 시 스택을 해제하는 기능을 포함하여 컨티뉴에이션과 유사한 동작을 할 수 있다.


=== COME FROM 문 ===

COME FROM 문은 goto 문의 작동 방식을 뒤집은 패러디적인 제어 구조이다. 특정 레이블에 도달했을 때, 지정된 다른 위치에서 "왔다"고 간주하고 해당 위치로 제어를 옮기는 식이다. 주로 인터칼과 같은 난해한 프로그래밍 언어에서 사용된다.

=== Perl의 GOTO ===

언어의 `goto`는 다른 언어의 goto와는 다소 다르게 작동한다. `goto 레이블` 형태 외에 `goto 함수이름` 형태로 사용될 수 있는데, 이는 현재 실행 중인 서브루틴(함수)의 실행을 즉시 중단하고 지정된 다른 서브루틴을 호출하는 방식이다. 이때 단순히 함수를 호출하는 것과 달리, 현재 서브루틴의 호출 스택 정보를 새 서브루틴의 것으로 완전히 대체한다. 이는 꼬리 호출 최적화와 유사한 효과를 내며, 새 서브루틴이 종료되면 GOTO를 호출한 원래 서브루틴으로 돌아가는 것이 아니라, 원래 서브루틴을 호출했던 곳으로 바로 돌아간다.

=== 기타 변형 ===

  • '''COBOL''': 1985년 ANSI 표준 이전의 COBOL에서는 `ALTER` 문을 사용하여 이미 작성된 `GO TO` 문의 목적지를 동적으로 변경할 수 있었다.[7] 이는 코드의 유연성을 높이려는 의도였지만, 프로그램의 흐름을 예측하기 어렵게 만들어 많은 비판을 받았고 거의 사용되지 않았다.
  • '''PL/I''': `LABEL`이라는 데이터 타입을 제공하여 레이블 자체를 변수에 저장하거나 배열로 관리할 수 있게 했다. 이를 통해 계산된 goto나 할당된 goto와 유사한 기능을 구현할 수 있었으며, 심지어 현재 프로시저 블록 외부로 점프하는 것도 가능했다. 다른 프로시저에게 레이블을 인수로 전달하여 호출된 프로시저가 호출한 프로시저의 특정 지점으로 직접 점프하여 종료하는 것도 가능했다. 이 경우 점프 시 호출 스택이 자동으로 정리(pop)된다.

5. 대안

고급 언어에서 goto 문은 과도하게 사용될 경우 코드를 읽고 유지하기 어려운 스파게티 코드를 만들기 쉽다는 비판을 받아왔다. 1960년대1970년대구조적 프로그래밍이 부상하면서, 많은 컴퓨터 과학자들은 프로그램이 항상 'goto' 문 대신 순환문, 'if-then-else' 문과 같은 구조적 제어 흐름문을 사용해야 한다고 주장했다.[25] 에츠허르 데이크스트라1968년 "goto 문의 해로움"이라는 글에서 'goto' 문이 프로그램의 정확성을 분석하고 증명하는 것을 어렵게 만들기 때문에 제한해야 한다고 주장하며 이러한 비판의 계기가 되었다.[26][1]

'goto' 문 없이 프로그램을 구조화하는 주요 대안들은 다음과 같다.

'''구조적 프로그래밍'''

현대적인 서브루틴 개념은 EDSAC 프로그래밍 과정에서 데이비드 휠러에 의해 고안되었다. 그는 서브루틴 호출 명령어가 없는 기계에서 호출과 반환을 구현하기 위해 휠러 점프라는 자기 수정 코드 기법을 사용했다. 이는 라이브러리 루틴의 중첩 실행을 통해 프로그램을 구조화하는 길을 열었다.

이후 파스칼과 같은 고급 언어들은 구조적 프로그래밍을 지원하도록 설계되었다. 이 언어들은 서브루틴(프로시저 또는 함수)과 함께 다음과 같은 제어 구조를 도입하여 'goto' 문의 필요성을 줄였다.



이러한 구조들은 이전에 'goto'와 'if'를 조합하여 구현했던 제어 흐름을 대체했다. 특히 'switch' 문은 조건에 따라 동적으로 점프 대상을 결정하는 "계산된 goto"의 필요성을 줄였다. 뵈임-자코피니 정리는 모든 프로그램을 순차 실행, 조건 분기('if'), 반복('while')만으로 표현할 수 있음을 이론적으로 증명했지만, 실제 적용 시에는 코드가 복잡해질 수 있다는 문제도 제기되었다.

'''조기 종료 및 예외 처리'''

구조적 프로그래밍의 세 가지 기본 구조만을 엄격하게 따를 경우, 중첩이 깊어지고 모든 예외 상황을 처리하기 위해 프로그램 상태 관리가 복잡해지는 문제가 발생할 수 있다. 이를 해결하기 위해 구조적 단위(블록, 함수)를 중간에 빠져나오는 방법들이 도입되었다.

  • 조기 종료: C와 같은 언어에서는 'break' 문을 사용하여 루프를 즉시 종료하거나, 'continue' 문을 사용하여 다음 반복으로 넘어갈 수 있다. 이는 불필요한 'if'나 'while' 문 추가 없이 제어 흐름을 단순화한다. Java와 같은 일부 언어는 여러 단계의 중첩된 루프를 한 번에 빠져나올 수 있는 "레이블 있는 'break'" 기능을 제공하는데, 이는 'goto'의 흔한 사용 사례 중 하나를 대체한다.[5][10] Java 설명서에 따르면, 'goto' 문의 약 90%가 다단계 'break' 구현에 사용되었다고 한다.
  • 예외 처리: Java의 'try'/'catch'/'finally' 구문이나 C++의 RAII(Resource Acquisition Is Initialization) 기법은 프로그램 실행 중 발생하는 예외적인 상황을 처리하는 구조적인 방법을 제공한다. 예외 처리는 오류 발생 시 현재 실행 지점에서 벗어나 지정된 예외 처리 코드로 제어를 옮긴다. 이는 자원 해제와 같은 정리 작업을 수행하는 데 유용하며, C 언어에서 'goto'가 자주 사용되던 오류 처리 패턴[5][10]을 대체할 수 있다.[19][20] C 언어의 'setjmp'/'longjmp' 함수도 유사한 기능을 제공하지만, 예외 처리 메커니즘은 남용될 경우 'goto'처럼 코드 흐름을 이해하기 어렵게 만들 수 있다는 비판도 있다.


'''꼬리 호출 최적화'''

1977년 가이 L. 스틸은 프로시저(함수)의 마지막 작업이 다른 프로시저를 호출하는 것(꼬리 호출)일 경우, 새로운 스택 프레임을 생성하지 않고 현재 스택 프레임을 재사용하여 직접적인 제어 이동(마치 'goto'처럼)으로 최적화할 수 있다고 주장했다. 이는 Lisp와 같이 프로시저 호출이 빈번한 언어에서 특히 중요하며, 프로시저 호출 비용이 'goto'보다 비싸다는 통념을 반박했다.

Scheme과 같은 언어는 꼬리 호출 최적화를 언어 표준으로 요구한다. 이 최적화를 통해 꼬리 재귀(함수가 자기 자신을 꼬리 호출하는 것)를 사용하여 스택 오버플로 걱정 없이 반복문을 효율적으로 구현할 수 있다. 또한, 여러 함수가 서로를 꼬리 호출하는 상호 재귀를 통해 유한 상태 기계와 같은 복잡한 제어 흐름을 'goto' 없이 구현하는 것도 가능하다.

'''코루틴'''

코루틴은 여러 개의 진입점과 종료점을 가질 수 있어, 일반적인 서브루틴보다 유연한 제어 흐름을 제공한다. 'goto'처럼 임의의 지점으로 점프하는 대신, 코루틴은 특정 지점('yield')에서 실행을 잠시 멈추고 다른 코루틴에게 제어를 넘겼다가, 나중에 멈췄던 지점부터 실행을 재개할 수 있다. 이는 협력적 멀티태스킹이나 제너레이터(데이터 스트림 생성)와 같은 특정 종류의 문제를 해결하는 데 유용하다. 클로저와 'switch' 문을 결합하여 코루틴과 유사한 동작을 구현하는 것도 가능하다(C 언어에서 사용되는 기법).

'''메시지 전달'''

객체 지향 프로그래밍이나 병행 컴퓨팅 환경에서는 메시지 전달이 중요한 제어 흐름 메커니즘으로 사용된다. 각 객체나 프로세스는 독립적으로 동작하며, 서로에게 메시지를 보내 상호작용한다. 전체 시스템의 제어 흐름은 개별 구성 요소의 직접적인 점프가 아니라, 이러한 메시지 교환과 스케줄링(예: 선점)에 의해 결정된다. 시뮬라스몰토크와 같은 초기 객체 지향 언어들이 이러한 개념을 도입했으며, 캡슐화를 통해 상태 관리를 용이하게 하여 복잡성을 줄였다.

'''기타 현대적 접근'''

Haskell과 같은 함수형 언어에서는 모나드를 사용하여 예외 처리, 비결정적 계산 등 다양한 제어 구조를 추상적으로 표현한다. Smalltalk나 Io 같은 언어에서는 제어 구조 자체를 객체(코드 블록)와 메서드 호출로 다룬다. Scheme의 계속(continuation)은 프로그램의 특정 실행 상태를 저장했다가 나중에 그 상태로 돌아갈 수 있게 하는 강력한 기능으로, "인자 있는 goto"라고 불리기도 한다. 이러한 고수준의 제어 구조들은 저수준의 'goto' 문을 사용할 필요성을 크게 줄여준다.

6. 언어 지원

많은 프로그래밍 언어는 `goto` 문을 지원하지만, 그렇지 않은 언어도 많다.

'''지원하는 언어'''


  • C: `goto` 문을 지원하며, 오류 처리나 다중 루프 탈출 등 특정 상황에서 사용되기도 한다.[1][2] 리눅스 커널 코드에서도 사용 예를 찾아볼 수 있다.
  • C#: `goto`를 지원하지만, 현재 실행 중인 코드 블록 밖으로 점프하는 것은 허용되지 않는다. switch 문 내에서 `case`나 `default` 레이블로 이동하는 데 사용될 수 있다 (`goto case`, `goto default`).[9]
  • 비주얼 베이직 .NET: `goto`를 지원하며, C#과 유사한 제약을 가진다.[9]
  • PL/I: `goto` 문을 지원하며, 블록 외부로 이동할 때 스택을 정리하지만 블록 외부에서 내부로의 이동은 허용하지 않는다.
  • 포트란: 과거에는 `goto`가 널리 사용되었으나, 구조적 프로그래밍 기능이 도입되면서 사용이 제한되었다. 특정 형태의 `goto`는 이후 버전에서 삭제되었다.[3][4]
  • PHP: 버전 5.3부터 `goto` 문을 지원하기 시작했다. 이전 버전에서는 관련 기능을 구현한 라이브러리가 사용되기도 했다.[11][20]
  • Perl: 기본적으로 `next` 키워드를 사용하여 명시적인 폴스루(fallthrough)를 구현하지만, 설정을 통해 암시적 폴스루도 가능하다.
  • D: 1999년부터 설계된 비교적 최신 언어임에도 `goto` 문을 포함하고 있다.[19]
  • MAD: `TRANSFER TO` 라는 이름으로 `goto`와 유사한 기능을 제공했다.
  • APL: 오른쪽 화살표 기호(`→`)를 `goto` 문으로 사용한다.
  • 어셈블리어: 기계어의 무조건 분기와 레이블을 통해 `goto`와 동일한 기능을 구현한다.
  • 베이직: 초기 버전이나 단순한 형태의 BASIC에서는 분기나 반복을 위해 `goto` 문이 필수적인 경우가 많았다.


'''지원하지 않는 언어'''

  • 자바: `goto`가 예약어로 지정되어 있지만 실제로는 사용할 수 없다. 대신 레이블과 함께 사용하는 break나 continue 문을 통해 비슷한 기능을 일부 구현할 수 있다. 컴파일된 바이트코드(`.class` 파일) 수준에서는 GOTO 명령어가 사용된다.[8]
  • 파이썬: `goto` 문을 지원하지 않는다. 재미 삼아 `goto` 기능을 추가하는 비공식 모듈이 존재하기도 한다.
  • Seed7: `goto` 문을 지원하지 않으며, `break`나 `continue`와 같이 제어 흐름을 갑자기 바꾸는 문장도 의도적으로 배제했다.
  • 에이다: 구조적 프로그래밍 원칙을 강조하며 `goto` 사용을 지양하는 설계를 가지고 있다. 레이블을 정의할 때는 시각적 구분을 위해 꺽쇠괄호(`<<레이블>>`)를 사용한다.
  • 함수형 프로그래밍 언어 (예: Scheme): 일반적으로 `goto` 대신 연속(continuation)과 같은 다른 제어 구조를 사용한다.


'''기타 제어 흐름 메커니즘'''

`goto`를 지원하지 않는 언어들은 대안적인 제어 흐름 메커니즘을 제공하는 경우가 많다. 예를 들어, break나 continue 문은 반복문이나 선택문에서 벗어나거나 다음 반복으로 넘어가는 데 사용된다. 예외 처리 메커니즘 역시 특정 상황에서 코드의 실행 흐름을 다른 곳으로 옮기는 역할을 할 수 있다. Go 언어는 `switch` 문에서 다음 `case`로 실행을 이어가기 위해 `fallthrough`라는 명시적인 키워드를 사용한다.

7. 현재 상황

구조적 프로그래밍의 등장 이후, goto 문은 스파게티 코드를 유발할 수 있다는 비판을 받으며 사용이 줄어드는 추세이다.[25] 특히 1968년 에츠허르 데이크스트라가 "goto 문의 해로움"[26]이라는 글을 통해 goto 문이 프로그램의 정확성 분석과 증명을 어렵게 만든다고 주장한 이후, 많은 프로그래밍 언어에서 goto 사용을 제한하거나 다른 제어 구조(예: 반복문, if-then-else 문) 사용을 권장하게 되었다.[1]

하지만 특정 상황에서는 goto 문이 여전히 유용하다는 주장도 꾸준히 제기되었다. 도널드 커누스는 goto 문이 특정 프로그래밍 구조가 언어에 없을 때 이를 모방하는 기본적인 요소가 될 수 있다고 보았다.[27] 브라이언 커니핸데니스 리치 역시 goto 문이 남용될 위험이 크다고 경고하면서도, C 언어에서 중첩된 루프를 한 번에 빠져나가거나 함수 끝에서 오류를 처리하는 등의 제한적인 상황에서는 유용할 수 있다고 언급했다. 실제로 C 프로그래밍에서는 이러한 용법이 흔하며, 특히 내장된 예외 처리 기능 부족으로 오류 처리 패턴에서 goto가 사용되기도 한다.

리눅스 커널과 같은 대규모 프로젝트에서도 goto 문은 여전히 사용되고 있다. 리누스 토르발스를 비롯한 일부 개발자들은 goto 문을 적절히 사용하면 프로그램의 속도, 크기, 코드 명확성을 향상시킬 수 있다고 주장한다. 2013년 기준으로 리눅스 커널 코드에는 약 10만 개의 goto 문이 사용된 것으로 알려졌다.

현재 C 언어를 제외한 많은 주류 언어에서는 goto 문을 거의 사용하지 않는다. Java나 Python 같은 언어는 아예 goto 문을 지원하지 않는다. 대신 break, continue, 예외 처리, 꼬리 호출 최적화, RAII(C++) 등 더 구조화된 방식으로 제어 흐름을 다루는 기능을 제공한다. Java의 경우, goto 키워드는 예약되어 있지만 실제 기능은 구현되지 않았고, 대신 레이블을 지정하여 여러 단계의 루프를 탈출할 수 있는 `break` 및 `continue` 문을 제공한다. 이는 C에서 goto 문의 가장 흔한 사용 사례(다단계 탈출)를 대체하기 위한 것이다.

반면, PHP(버전 5.3부터)[11][20], D 언어[19], C# 등 일부 현대 언어에서는 여전히 제한적인 형태로나마 goto 문을 지원하고 있어, 특정 상황에서의 유용성을 인정받고 있음을 보여준다.

goto 문이 유용하게 사용될 수 있는 대표적인 상황은 다음과 같다.


  • 중첩된 루프나 조건문에서 한 번에 빠져나와야 할 때 (다단계 break/continue 기능이 없는 경우).
  • 오류 발생 시 함수 뒷부분의 정리 코드(예: 할당된 자원 해제)로 바로 이동해야 할 때 (특히 예외 처리 기능이 없거나 비효율적인 언어).
  • 유한 상태 기계를 구현할 때 상태 전환을 명확하게 표현하기 위해.
  • 코드를 재구성하기 어려운 레거시 코드를 수정할 때 임시방편으로 사용될 수도 있다.


결론적으로, goto 문은 무분별하게 사용될 경우 코드의 구조를 해치고 가독성을 떨어뜨릴 수 있어 현대 프로그래밍에서는 사용을 지양하는 경향이 강하다. 하지만 C 언어와 같이 저수준 제어가 필요하거나 특정 패턴 구현에 유용한 경우, 혹은 다른 제어 구조보다 goto를 사용하는 것이 더 명확하고 효율적인 예외적인 상황에서는 여전히 그 쓰임새를 찾을 수 있다. 프로그래밍 커뮤니티에서는 goto 사용에 대해 여전히 다양한 의견이 존재하며, 무조건적인 금지보다는 상황에 맞는 현명한 사용을 강조하는 시각이 많다.

애플의 SSL/TLS 구현에서 발견된 유명한 보안 취약점인 CVE-2014-1266(일명 'goto fail' 버그)는 goto 문 자체의 문제라기보다는, 코드 중복 작성 과정에서 goto 문이 잘못된 위치에 삽입되어 필수적인 보안 검증 로직을 건너뛰게 된 것이 원인이었다. 이는 goto 사용 시 주의 깊은 코딩과 충분한 테스트가 필요함을 보여주는 사례이다.

참조

[1] 인용구
[2] EWD On a Somewhat Disappointing Correspondence 1987-05
[3] 간행물 American National Standard – Programming Language FORTRAN American National Standards Institute 1978
[4] 간행물 Information technology – Programming languages – Fortran – Part 1: Base language ISO/IEC
[5] 웹사이트 nathanhoad/godot_dialogue_manager https://github.com/n[...] 2022-07-28
[6] 설명
[7] 설명
[8] 인용
[9] 웹사이트 GoTo Statement - Visual Basic https://learn.micros[...] 2021-09-15
[10] 웹사이트 ha ha only serious http://catb.org/~esr[...]
[11] 웹사이트 PHP: 新機能 - Manual http://www.php.net/m[...]
[12] 서적 文芸的プログラミング
[13] 학술지 Go To Statement Considered Harmful
[14] 학술지 Structured Programming with go to Statements Computing Surveys
[15] 논문 Structured Programming http://homepages.cs.[...] NATO Scientific Affairs Division, Brussels, Belgium
[16] 논문 '"GOTO Considered Harmful" Considered Harmful' https://web.archive.[...]
[17] 학술지 GO TO 論争:第2部 GO TO 論争 共立出版
[18] 학술지 "構造的プログラミング −批判と支持−" 共立出版
[19] 웹사이트 Language Reference Goto Statement http://dlang.org/sta[...]
[20] 웹사이트 PHP マニュアル goto http://php.net/manua[...]
[21] 학술지 "GO TO 論争:第3部 解説" 共立出版
[22] 서적 소프트웨어クリーンルーム手法 日科技連
[23] 학술지 "ダイクストラ教授とふた付き命令" 共立出版
[24] 웹사이트 All Circuits are Busy Now: The 1990 AT&T Long Distance Network Collapse http://users.csc.cal[...]
[25] 서적 C 언어 프로그래밍 대영사
[26] 웹사이트 Go To Statement Considered Harmful http://www.acm.org/c[...]
[27] 웹사이트 Structured Programming with Goto Statements http://pplab.snu.ac.[...]



본 사이트는 AI가 위키백과와 뉴스 기사,정부 간행물,학술 논문등을 바탕으로 정보를 가공하여 제공하는 백과사전형 서비스입니다.
모든 문서는 AI에 의해 자동 생성되며, CC BY-SA 4.0 라이선스에 따라 이용할 수 있습니다.
하지만, 위키백과나 뉴스 기사 자체에 오류, 부정확한 정보, 또는 가짜 뉴스가 포함될 수 있으며, AI는 이러한 내용을 완벽하게 걸러내지 못할 수 있습니다.
따라서 제공되는 정보에 일부 오류나 편향이 있을 수 있으므로, 중요한 정보는 반드시 다른 출처를 통해 교차 검증하시기 바랍니다.

문의하기 : help@durumis.com